# $@ = target file
# $< = first dependency
# $^ = all dependencies

CC = /usr/bin/g++
GDB = /usr/bin/gdb
LD = /usr/bin/ld
CFLAGS = -g -m32 -fno-pie -Wall -ffreestanding -c
LDFLAGS = -m elf_i386
QEMU = qemu-system-i386
# Automatically  expand  to a list of  existing  files  that# match  the  patterns
C_SOURCES = $(wildcard  kernel/*.c drivers/*.c)
HEADERS = $(wildcard  kernel/*.h drivers/*.h)
CPP_SOURCES = ${wildcard kernel/*.cpp drivers/*.cpp}

# Create a list of  object  files  to build , simple  by  replacing# the  ’.c’
# extension  of  filenames  in  C_SOURCES  with  ’.o’
OBJ = ${C_SOURCES:.c=.o}
OBJCPP = ${CPP_SOURCES:.cpp=.o}

# First rule is the one executed when no parameters are fed to the Makefile
all: run

run: build
	# ${QEMU} -nographic -fda os-image.bin
	${QEMU} -vga std -fda os-image.bin


debug : os-image.bin kernel.elf
	${QEMU} -vga std -fda os-image.bin -gdb tcp::1234 -S &
	${GDB} -ex "target remote localhost:1234" -ex "symbol-file kernel.elf"

build: os-image.bin

os-image.bin: boot/boot.bin kernel.bin
	cat $^ > $@

# Link  kernel  object  files  into  one binary , making  sure  the
# entry  code is  right  at the  start  of the binary.
kernel.bin: kernel/kernel_entry.o ${OBJCPP} ${OBJ} 
	${LD} ${LDFLAGS} -o $@ -Ttext 0x1000 $^ --oformat  binary

kernel.elf: kernel/kernel_entry.o ${$OBJCPP} ${OBJ} 
	${LD} ${LDFLAGS} -o $@ -Ttext 0x1000 $^


# Generic  rule  for  building  ’somefile.o’ from ’somefile.c’
%.o : %.c ${HEADERS}
	${CC} ${CFLAGS} $< -o $@

%.o : %.cpp ${HEADERS}
	${CC} ${CFLAGS} $< -o $@


%.o: %.asm
	${NASM} $< -f elf32 -o $@


%.bin: %.asm
	${NASM} $< -f bin -o $@

clean:
	rm **/*.o
	rm **/*.bin
	rm *.bin
	rm *.elf
